<?php
namespace Tbf\Bundle\AlipayBundle\Entity;
use Doctrine\ORM\Mapping as ORM;

/**
 * 支付宝交易事务,
 * 以应用传过来的tradeid作为主键
 *
 * 担保交易的交易状态变更顺序依次是：
 *      WAIT_BUYER_PAY
 *      WAIT_SELLER_SEND_GOODS
 *      WAIT_BUYER_CONFIRM_GOODS
 *      TRADE_FINISHED
 * 即时到账的交易状态变更顺序依次是：
 *      WAIT_BUYER_PAY
 *      TRADE_FINISHED
 *
 * @ORM\Table(name="tbf_alipay_transaction")
 * @ORM\Entity
 * @ORM\HasLifecycleCallbacks
 */
class Transaction {
    /** 这个交易是由"即时到帐接口"创建的 */
    const TYPE_CREATE_DIRECT_PAY_BY_USER='create_direct_pay_by_user';
    /** 这个交易是由"纯担保交易接口"创建的 */
    const TYPE_CREATE_PARTNER_TRADE_BY_BUYER='create_partner_trade_by_buyer';
    /** 这个交易是由"标准双接口"创建的 */
    const TYPE_CREATE_TRADE_BY_USER='create_trade_by_user';

    /** 即使到帐支付方式 */
    const TYPE_DIRECT_PAY='direct_pay';
    /** 担保交易支付方式 */
    const TYPE_PARTNER_TRADE='partner_trade';
    /** 支付方式未知(标准双接口,用户还没选) */
    const TYPE_UNKNOWN='unknown';

    /**
     * 交易状态
     * 等待api的返回值
     */
    const STATUS_WAIT_API_RESPONSE='WAIT_API_RESPONSE';
    /**
     * 交易创建，等待买家付款。(担保,即时)
     * 触发(担保)
     */
    const STATUS_WAIT_BUYER_PAY='WAIT_BUYER_PAY';
    /**
     * 买家已付款，等待卖家发货(担保)
     */
    const STATUS_WAIT_SELLER_SEND_GOODS='WAIT_SELLER_SEND_GOODS';
    /** 卖家已发货，等待买家确认(担保) */
    const STATUS_WAIT_BUYER_CONFIRM_GOODS='WAIT_BUYER_CONFIRM_GOODS';
    /**
     * 这个事务完成了,后续重复的完成消息不发回调(担保,即时)
     * 交易成功且结束，即不可再做任何操作
     * 触发 (担保,即时)
     */
    const STATUS_TRADE_FINISH='TRADE_FINISHED';
    /**
     * 支付成功 (即时)
     * 交易成功，且可对该交易做操作，如：多级分润、退款等。
     * 触发 (担保,即时)
     */
    const STATUS_TRADE_SUCCESS='TRADE_SUCCESS';
    /**
     * 交易中途关闭（已结束，未成功完成）(担保,即时)
     * 在指定时间段内未支付时关闭的交易；(即时)
     * 在交易完成全额退款成功时关闭的交易。(即时)
     * 触发(担保)
     */
    const STATUS_TRADE_CLOSED='TRADE_CLOSED';
    /** 等待卖家收款（买家付款后，如果卖家账号被冻结）。(即时) */
    const STATUS_TRADE_PENDING='TRADE_PENDING';

    /**
     * @var string
     * @ORM\Id
     * @ORM\Column()
     */
    protected $id;

    /**
     * 创建交易的方式(三种)
     * @var string
     *
     * @ORM\Column()
     */
    protected $create_payment_type;

    /**
     * 支付方式(二种)
     * @var string
     *
     * @ORM\Column()
     */
    protected $payment_type=self::TYPE_UNKNOWN;

    /**
     * @var float
     *
     * @ORM\Column(type="float")
     */
    protected $money;

    /**
     * @var string
     *
     * @ORM\Column(type="binary")
     * func(response CreateDirectByUserResponse)(err error)
     */
    protected $api_callback;

    /**
     * @var string
     *
     * @ORM\Column(type="binary")
     * func(response CreateDirectByUserResponse)(err error)
     */
    protected $page_callback;

    /**
     * @var \DateTime
     *
     * @ORM\Column(type="datetime")
     */
    protected $add_time;

    /**
     * @var \DateTime
     *
     * @ORM\Column(type="datetime")
     */
    protected $update_time;

    /**
     * @var string
     *
     * @ORM\Column()
     */
    protected $subject;

    /**
     * @var string
     *
     * @ORM\Column()
     */
    protected $status = self::STATUS_WAIT_API_RESPONSE;

    /**
     * 附加数据(保存序列化好的字符串)
     * @var string
     *
     * @ORM\Column(type="binary")
     */
    protected $extra_data;

    /** @ORM\PrePersist */
    public function onPrePersist()
    {
        $this->add_time = new \DateTime();
        $this->update_time = new \DateTime();
    }
    /** @ORM\PreUpdate */
    public function onPreUpdate(){
        $this->update_time = new \DateTime();
    }
    /**
     * @param string $api_callback
     */
    public function setApiCallback($api_callback)
    {
        $this->api_callback = $api_callback;
    }

    /**
     * @return string
     */
    public function getApiCallback()
    {
        return $this->api_callback;
    }

    /**
     * @param string $id
     */
    public function setId($id)
    {
        $this->id = $id;
    }

    /**
     * @return string
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * @param float $money
     */
    public function setMoney($money)
    {
        $this->money = $money;
    }

    /**
     * @return float
     */
    public function getMoney()
    {
        return $this->money;
    }

    /**
     * @param string $page_callback
     */
    public function setPageCallback($page_callback)
    {
        $this->page_callback = $page_callback;
    }

    /**
     * @return string
     */
    public function getPageCallback()
    {
        return $this->page_callback;
    }

    /**
     * @param string $subject
     */
    public function setSubject($subject)
    {
        $this->subject = $subject;
    }

    /**
     * @return string
     */
    public function getSubject()
    {
        return $this->subject;
    }

    /**
     * @return \DateTime
     */
    public function getAddTime()
    {
        return $this->add_time;
    }


    /**
     * @return \DateTime
     */
    public function getUpdateTime()
    {
        return $this->update_time;
    }

    /**
     * @param string $status
     */
    public function setStatus($status)
    {
        $this->status = $status;
        $this->setPaymentTypeByStatus($status);
    }
    protected function setPaymentTypeByStatus($status){
        if ($this->payment_type!==self::TYPE_UNKNOWN){
            return;
        }
        //出现过这个两个状态,表明是担保交易
        if (in_array($status,array(
            self::STATUS_WAIT_SELLER_SEND_GOODS,
            self::STATUS_WAIT_BUYER_CONFIRM_GOODS
        ))){
            $this->payment_type =  self::TYPE_PARTNER_TRADE;
            return;
        }
        //直接结束,表明是即时到帐
        if ($status===self::STATUS_TRADE_FINISH &&
            $this->payment_type !== self::TYPE_PARTNER_TRADE
        ){
            $this->payment_type = self::TYPE_DIRECT_PAY;
            return;
        }

    }
    /**
     * @return string
     */
    public function getStatus()
    {
        return $this->status;
    }

    /**
     * @param string $extra_data
     */
    public function setExtraData($extra_data)
    {
        $this->extra_data = json_encode($extra_data);
    }

    /**
     * @return string
     */
    public function getExtraData()
    {
        return json_decode($this->extra_data,true);
    }

    /**
     * @param string $create_payment_type
     */
    public function setCreatePaymentType($create_payment_type)
    {
        $this->create_payment_type = $create_payment_type;

        if ($this->create_payment_type===self::TYPE_CREATE_DIRECT_PAY_BY_USER){
            $this->payment_type = self::TYPE_DIRECT_PAY;
        }elseif ($this->create_payment_type===self::TYPE_CREATE_PARTNER_TRADE_BY_BUYER){
            $this->payment_type = self::TYPE_PARTNER_TRADE;
        }
    }

    /**
     * @return string
     */
    public function getCreatePaymentType()
    {
        return $this->create_payment_type;
    }

    /**
     * @return string
     */
    public function getPaymentType()
    {
        return $this->payment_type;
    }

    /**
     * 交易是否完成
     * @return bool
     */
    public function isFinish(){
        if (in_array($this->status,array(
            self::STATUS_TRADE_FINISH,
            self::STATUS_TRADE_SUCCESS
        ))){
            return true;
        }
        return false;
    }
    /**
     * 用户是否支付
     * 立即到帐 -> 支付,完成,
     * 担保交易 -> 买家支付等待卖家付款,完成
     * @return bool
     */
    public function hasPay(){
        if ($this->isFinish()){
            return true;
        }
        if (in_array($this->status,array(
            self::STATUS_WAIT_SELLER_SEND_GOODS,
            self::STATUS_WAIT_BUYER_CONFIRM_GOODS
        ))){
            return true;
        }
        return false;
    }

    /**
     * 交易是否关闭
     * 被用户关闭...
     * @return bool
     */
    public function isClose(){
        if (in_array($this->status,array(
            self::STATUS_TRADE_CLOSED
        ))){
            return true;
        }
        return false;
    }

    /**
     * 是否是用户完成订单(担保交易,用户确认收货)
     */
    public function isUserFinish(){
        if ($this->getPaymentType()===self::TYPE_PARTNER_TRADE &&
            $this->getStatus()===self::STATUS_TRADE_FINISH
        ){
            return true;
        }
        return false;
    }
}